import React from 'react'
import Alert from 'react-aaui/es/alert'
import configureStore from 'redux-mock-store'
import { mount } from 'enzyme'

import { Root } from 'root'
import errorMiddleware from 'middlewares/errorMiddleware'

const setup = (props = {}) => {
  const mockStore = configureStore([errorMiddleware])
  const store = mockStore({})

  const l10n = {
    formatMessage: m => m,
  }
  const view = () => <h1>View</h1>
  const system = { loading: false }
  const Component = (
    <Root store={store} view={view} system={system} l10n={l10n} {...props} />
  )
  const wrapper = mount(Component)

  return {
    wrapper,
    Component,
    store,
  }
}

it('should render without errors', () => {
  const { wrapper } = setup()

  expect(wrapper).toBeTruthy()
})

it('should render without errors when setting loading as true', () => {
  const { wrapper } = setup({
    system: {
      loading: true,
    },
  })

  expect(wrapper).toBeTruthy()
})

it('should render error message as Modal when passing `errorModal`', () => {
  const { Component } = setup({
    system: {
      errorModal: 'error message',
    },
  })

  expect(Component).toMatchSnapshot()
})

it('should render error message as Alert when passing `alert`', () => {
  const errorAlertMock = jest.fn()
  const { wrapper } = setup({
    errorAlert: errorAlertMock,
  })
  const onCloseMock = jest.fn()
  const alertErrorMock = jest.fn(() => ({
    close: onCloseMock,
  }))
  const errorMessage = 'i am a alert message'

  Alert.error = alertErrorMock

  wrapper.setProps({
    system: {
      errorAlert: errorMessage,
    },
  })

  expect(alertErrorMock).toBeCalled()
  expect(alertErrorMock).toBeCalledWith(
    expect.objectContaining({
      message: errorMessage,
    }),
  )

  wrapper.setProps({
    system: {
      errorAlert: '',
    },
  })

  expect(onCloseMock).toBeCalled()
  expect(alertErrorMock).toHaveBeenCalledTimes(1)
})

it('should render error message as Alert when passing multiple `alert`', () => {
  const errorAlertMock = jest.fn()
  const { wrapper } = setup({
    errorAlert: errorAlertMock,
  })
  const onCloseMock = jest.fn()
  const alertErrorMock = jest.fn(() => ({
    close: onCloseMock,
  }))
  const errorMessage = 'i am a alert message'
  const errorMessage1 = 'i am a alert message1'
  const errorMessage2 = 'i am a alert message2'

  Alert.error = alertErrorMock

  wrapper.setProps({
    system: {
      errorAlert: errorMessage,
    },
  })
  wrapper.setProps({
    system: {
      errorAlert: errorMessage,
    },
  })
  wrapper.setProps({
    system: {
      errorAlert: errorMessage1,
    },
  })
  wrapper.setProps({
    system: {
      errorAlert: errorMessage2,
    },
  })

  wrapper.setProps({
    system: {
      errorAlert: '',
    },
  })

  expect(onCloseMock).toBeCalled()
  expect(onCloseMock).toHaveBeenCalledTimes(3)
  expect(alertErrorMock).toHaveBeenCalledTimes(3)
})

it('should render modal when passing `modal` object', () => {
  const { Component } = setup({
    system: {
      modal: { view: () => <div>modal</div>, data: { tip: 'abc' } },
    },
  })

  expect(Component).toMatchSnapshot()
})
